/* controller层逻辑处理 */
// 导入并注册ajv
const Ajv = require('ajv')
const ajv = new Ajv()
// 导入校验规则schema
const { userRegisterSchema } = require('../validator/user')
const { getUserService, registerUserService, getUserDataService } = require('../service/user')
const { ErrorModel, SuccessModel } = require('../model/result')
const { registerValidateFail, registerExistsFail, registerServiceFail, loginValidateFail, loginExistsFail, loginServiceFail, loginPwdFail } = require('../config/error/user')
const generatePwd = require('../utils/crypto')

// 用户数据校验
const _userRegisterValidate = (data) => {
  return ajv.validate(userRegisterSchema, data)
}
// 用户是否存在
const _userIsExists = async (username) => {
  // 查询用户
  const users = await getUserService(username)
  return users.length
}
// 密码是否正确
const _userDataValidate = async (username, password) => {
  // 查询用户并验证账号密码 由于存储的密码是加密的, 所以登录时也要用加密的密码去登录
  return await getUserDataService(username, generatePwd(password))
}
/**
 * 用户注册
 * @param data req.body 数据
 * @returns {Promise<ErrorModel|SuccessModel>}
 */
const handleUserRegister = async (data) => {
  const { username, password, gender } = data
  // 1.数据格式校验
  const valid = _userRegisterValidate(data)
  if (!valid) {
    return new ErrorModel(registerValidateFail)
  }
  // 2.用户是否存在
  const exist = await _userIsExists(username)
  if (exist) {
    return new ErrorModel(registerExistsFail)
  }
  // 3.创建用户
  try {
    // 密码加密之后再存储
    await registerUserService({ username, password: generatePwd(password), gender })
    return new SuccessModel({
      message: '用户注册成功'
    })
  } catch (e) {
    return new ErrorModel(registerServiceFail)
  }
}

// 用户登录
const handleUserLogin = async (data) => {
  const { username, password } = data
  // 1.登录数据校验
  const valid = _userRegisterValidate(data)
  if (!valid) {
    return new ErrorModel(loginValidateFail)
  }
  // 2.用户是否存在
  const exist = await _userIsExists(username)
  if (!exist) {
    return new ErrorModel(loginExistsFail)
  }
  // 3.账号/密码是否正确
  const users = await _userDataValidate(username, password)
  if (!users.length) {
    return new ErrorModel(loginPwdFail)
  }
  // 4.登录成功，返回用户信息
  try {
    return new SuccessModel({
      message: '登录成功',
      data: users[0]
    })
  } catch (e) {
    return new ErrorModel(loginServiceFail)
  }
}

module.exports = {
  handleUserRegister,
  handleUserLogin
}
